#include <Windows.h>
#include <stdint.h>
#include <stdio.h>
#include <comdef.h>

#include "LocalServer_i.c"
#include "IHelloWorld.hpp"
#include "CMyComClass.hpp"
#include "CMyComClassFactory.hpp"

uint32_t gdwDllLockCount = 0;

/*
LocalServer basics

- Starts from an IDL file which defines the CLSID and contained interfaces.
- 
HKEY_CLASSES_ROOT\CLSID\{cdc32574-7521-4124-90c3-8d5605a34933}
Default = Name (REG_SZ)
AppId = {cdc32574-7521-4124-90c3-8d5605a34933} (REG_SZ)

HKEY_CLASSES_ROOT\CLSID\{cdc32574-7521-4124-90c3-8d5605a34933}\LocalServer32
Default = Path of EXE (and command line if applicable) (REG_EXPAND_SZ)
*/

int APIENTRY wWinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	wchar_t*     lpCmdLine,
	int       nCmdShow)
{
	// Init COM.
	HRESULT hr;
	AllocConsole();
	freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
	MessageBoxW(NULL, L"MyCar Server [LOCAL] is initilizing", L"[LOCAL]EXE Message!", MB_OK | MB_SETFOREGROUND);
	CoInitialize(NULL);

	// Let's register the type lib to get the 'free' type library marsahler.
	ITypeLib* pTLib = NULL;
	hr = LoadTypeLibEx(L"LocalServer.tlb", REGKIND_REGISTER, &pTLib);
	pTLib->Release();
	if (FAILED(hr))
	{
		exit(1);
	}

	printf("... command line: %ws\r\n", lpCmdLine);
	// Let's see if we were started by SCM.
	if (wcsstr(lpCmdLine, L"/Embedding") || wcsstr(lpCmdLine, L"-Embedding")) {
		// for debug
		MessageBoxW(NULL, L"MyCar Server[LOCAL] is registering the classes", L"[LOCAL]EXE Message!", MB_OK | MB_SETFOREGROUND);

		// Create the MyCar class object.
		CMyComClassFactory Factory;

		// Register the MyCar Factory.
		DWORD regID = 0;
		hr = CoRegisterClassObject(CLSID_CMyComClass, (IClassFactory*)&Factory,
			CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &regID);
		if (FAILED(hr))
		{
			printf("... failed to register class (error 0x%08x)\r\n", hr);
			CoUninitialize();
			exit(1);
		}
		else {
			printf("... successfully registered class\r\n");
		}
		// Now just run until a quit message is sent,
		// in responce to the final release.
		MSG ms;
		while (GetMessage(&ms, 0, 0, 0))
		{
			TranslateMessage(&ms);
			DispatchMessage(&ms);
		}

		// All done, so remove class object.
		CoRevokeClassObject(regID);
	}

	// Terminate COM.
	CoUninitialize();
	MessageBoxW(NULL, L"[LOCAL] Server is dying", L"[LOCAL]EXE Message!", MB_OK | MB_SETFOREGROUND);
	return 0;
}